import { formatFileSize } from './utils/helpers.js';

export class FileHandler {
  constructor(app) {
    this.app = app;
  }

  async handleFileUpload(file) {
    if (file.type.startsWith('image/')) {
      await this.handleImageUpload(file);
    } else if (file.type.startsWith('video/')) {
      await this.handleVideoUpload(file);
    } else {
      await this.sendFile(file);
    }
  }

  async handleImageUpload(file) {
    try {
      const base64 = await this.readFileAsBase64(file);
      this.app.connectionManager.sendMessage({
        type: 'image',
        url: base64,
        filename: file.name
      });
    } catch (error) {
      console.error('图片上传失败:', error);
      alert('图片上传失败，请重试');
    }
  }

  async handleVideoUpload(file) {
    try {
      const thumbnail = await this.generateVideoThumbnail(file);
      await this.sendFile(file, thumbnail);
    } catch (error) {
      console.error('视频上传失败:', error);
      await this.sendFile(file); // 如果缩略图生成失败，仍然上传视频
    }
  }

  async sendFile(file, thumbnail = null) {
    const chunkSize = 1024 * 1024; // 1MB chunks
    const totalChunks = Math.ceil(file.size / chunkSize);
    let currentChunk = 0;
    let totalLoaded = 0;

    this.app.domManager.showProgress(file.name, file.size);

    const fileStartMessage = {
      type: 'fileStart',
      filename: file.name,
      fileType: file.type,
      size: file.size,
      thumbnail: thumbnail
    };

    this.app.connectionManager.sendMessage(fileStartMessage);

    const sendNextChunk = () => {
      if (currentChunk >= totalChunks) {
        this.app.connectionManager.sendMessage({ type: 'fileEnd' });
        this.app.domManager.updateProgressStatus('正在写入文件...');
        return;
      }

      const start = currentChunk * chunkSize;
      const end = Math.min(start + chunkSize, file.size);
      const chunk = file.slice(start, end);

      const reader = new FileReader();
      reader.onload = () => {
        if (this.app.connectionManager.socket?.readyState === WebSocket.OPEN) {
          this.app.connectionManager.socket.send(reader.result);
          currentChunk++;
          totalLoaded += chunk.size;

          const progress = (totalLoaded / file.size) * 100;
          this.app.domManager.updateProgress(totalLoaded, file.size, progress);

          setTimeout(sendNextChunk, 0);
        }
      };

      reader.onerror = (error) => {
        console.error('文件读取错误:', error);
        this.app.domManager.hideProgress();
        alert('文件读取失败，请重试');
      };

      reader.readAsArrayBuffer(chunk);
    };

    sendNextChunk();
  }

  readFileAsBase64(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result);
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  }

  generateVideoThumbnail(file) {
    return new Promise((resolve) => {
      const video = document.createElement('video');
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');

      canvas.width = 320;
      canvas.height = 180;

      video.autoplay = false;
      video.muted = true;

      const videoUrl = URL.createObjectURL(file);

      const handleVideoLoad = () => {
        try {
          if (video.readyState >= 2) {
            video.currentTime = 1;

            video.onseeked = () => {
              try {
                const aspectRatio = video.videoWidth / video.videoHeight;
                let drawWidth = canvas.width;
                let drawHeight = canvas.width / aspectRatio;

                if (drawHeight > canvas.height) {
                  drawHeight = canvas.height;
                  drawWidth = canvas.height * aspectRatio;
                }

                const x = (canvas.width - drawWidth) / 2;
                const y = (canvas.height - drawHeight) / 2;

                ctx.fillStyle = '#000000';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(video, x, y, drawWidth, drawHeight);

                const thumbnail = canvas.toDataURL('image/jpeg', 0.8);

                video.removeEventListener('loadeddata', handleVideoLoad);
                URL.revokeObjectURL(videoUrl);
                resolve(thumbnail);
              } catch (error) {
                URL.revokeObjectURL(videoUrl);
                resolve(null);
              }
            };
          }
        } catch (error) {
          URL.revokeObjectURL(videoUrl);
          resolve(null);
        }
      };

      video.addEventListener('loadeddata', handleVideoLoad);

      video.onerror = () => {
        URL.revokeObjectURL(videoUrl);
        resolve(null);
      };

      video.src = videoUrl;
    });
  }

  formatFileSize(bytes) {
    return formatFileSize(bytes);
  }
} 